#include "E_Transform3.h"
#include<math.h>

void E_Transform3::SetMatrix(E_Point3* P, int Pt)
{
	this->P = P;
	this->PtrNum = Pt;
}

void E_Transform3::E_Translate(double tx, double ty, double tz)
{
	Identity();
	T[0][3] = tx; T[1][3] = ty; T[2][3] = tz;
	MultiplyMatrix();
}

void E_Transform3::E_RotateX(double thet)
{
	Identity();
	T[1][1] = cos(thet); T[1][2] = -sin(thet); T[2][1] = sin(thet); T[2][2] = cos(thet);
	MultiplyMatrix();
}

void E_Transform3::E_RotateY(double thet)
{
	Identity();
	T[0][0] = cos(thet); T[2][0] = -sin(thet); T[0][2] = sin(thet); T[2][2] = cos(thet);
	MultiplyMatrix();
}

void E_Transform3::E_RotateZ(double thet)
{
	Identity();
	T[0][0] = cos(thet); T[0][1] = -sin(thet); T[1][0] = sin(thet); T[1][1] = cos(thet);
	MultiplyMatrix();
}

void E_Transform3::E_RotatePX(double thet, E_Point3 P)
{
	E_Translate(-P.x, -P.y, -P.z);
	E_RotateX(thet);
	E_Translate(P.x, P.y, P.z);
}

void E_Transform3::E_RotatePY(double thet, E_Point3 P)
{
	E_Translate(-P.x, -P.y, -P.z);
	E_RotateY(thet);
	E_Translate(P.x, P.y, P.z);
}

void E_Transform3::E_RotatePZ(double thet, E_Point3 P)
{
	E_Translate(-P.x, -P.y, -P.z);
	E_RotateZ(thet);
	E_Translate(P.x, P.y, P.z);
}

void E_Transform3::E_RotatePXY(double thet, E_Point3 P)
{
	E_Translate(-P.x, -P.y, -P.z);
	E_RotateX(thet);
	E_RotateY(thet);
	E_Translate(P.x, P.y, P.z);
}

void E_Transform3::E_Scale(double dx, double dy, double dz)
{
	Identity();
	T[0][0] = dx; T[1][1] = dy; T[2][2] = dz;
	MultiplyMatrix();
}

void E_Transform3::E_ReflectZ()
{
	Identity();
	T[0][0] = -1; T[1][1] = -1; T[2][2] = 1;
	MultiplyMatrix();
}

void E_Transform3::E_ReflectX()
{
	Identity();
	T[0][0] = 1; T[1][1] = -1; T[2][2] = -1;
	MultiplyMatrix();
}

void E_Transform3::E_ReflectY()
{
	Identity();
	T[0][0] = -1; T[1][1] = 1; T[2][2] = -1;
	MultiplyMatrix();
}

void E_Transform3::E_ReflectZOX()
{
	Identity();
	T[0][0] = 1; T[1][1] = -1; T[2][2] = 1;
	MultiplyMatrix();
}

void E_Transform3::E_ReflectXOY()
{
	Identity();
	T[0][0] = 1; T[1][1] = 1; T[2][2] = -1;
	MultiplyMatrix();
}

void E_Transform3::E_ReflectYOZ()
{
	Identity();
	T[0][0] = -1; T[1][1] = 1; T[2][2] = 1;
	MultiplyMatrix();
}

void E_Transform3::E_ShearX(double b, double c)
{
	Identity();
	T[0][2] = b; T[0][3] = c; 
	MultiplyMatrix();
}

void E_Transform3::E_ShearY(double b, double c)
{
	Identity();
	T[1][0] = b; T[1][3] = c;
	MultiplyMatrix();
}

void E_Transform3::E_ShearZ(double b, double c)
{
	Identity();
	T[2][0] = b; T[2][1] = c;
	MultiplyMatrix();
}

void E_Transform3::Identity()
{
	T[0][0] = 1.0; T[0][1] = 0.0; T[0][2] = 0.0; T[0][3] = 0.0;
	T[1][0] = 0.0; T[1][1] = 1.0; T[1][2] = 0.0; T[1][3] = 0.0;
	T[2][0] = 0.0; T[2][1] = 0.0; T[2][2] = 1.0; T[2][3] = 0.0;
	T[3][0] = 0.0; T[3][1] = 0.0; T[3][2] = 0.0; T[3][3] = 1.0;
}

void E_Transform3::MultiplyMatrix()
{
	E_Point3* pNew = new E_Point3[PtrNum];
	for (int j = 0; j < PtrNum; j++) {
		pNew[j] = P[j];
	}
	for (int i = 0; i < PtrNum; i++) {
		P[i].x = pNew[i].x * T[0][0] + pNew[i].y * T[0][1] + pNew[i].z * T[0][2] + pNew[i].w * T[0][3];
		P[i].y = pNew[i].x * T[1][0] + pNew[i].y * T[1][1] + pNew[i].z * T[1][2] + pNew[i].w * T[1][3];
		P[i].z = pNew[i].x * T[2][0] + pNew[i].y * T[2][1] + pNew[i].z * T[2][2] + pNew[i].w * T[2][3];
		P[i].w = pNew[i].x * T[3][0] + pNew[i].y * T[3][1] + pNew[i].z * T[3][2] + pNew[i].w * T[3][3];
	}
}
